// -----------------------------------------------------------------------
//  <copyright file="AutoMapperModule.cs" company="LiuliuSoft">
//      Copyright (c) 2022-2022 DaprPlus. All rights reserved.
//  </copyright>
//  <site>https://www.dapr.plus</site>
//  <last-editor>郭明锋</last-editor>
//  <last-date>2022-12-09 18:57</last-date>
// -----------------------------------------------------------------------

using System.ComponentModel;

using DaprPlus.AutoMapper.Properties;

using Microsoft.Extensions.DependencyInjection.Extensions;

using OSharp.Localized;


namespace DaprPlus.AutoMapper;

/// <summary>
/// AutoMapper模块
/// </summary>
[LocalizedDescription("String_Module_AutoMapper", typeof(ResAutoMapper))]
public class AutoMapperModule : ModuleBase
{
    /// <summary>
    /// 获取 模块级别，级别越小越先启动
    /// </summary>
    public override ModuleLevel Level => ModuleLevel.Framework;

    /// <summary>
    /// 将模块服务添加到依赖注入服务容器中
    /// </summary>
    /// <param name="services">依赖注入服务容器</param>
    /// <returns></returns>
    public override IServiceCollection AddServices(IServiceCollection services)
    {
        services.TryAddSingleton(new MapperConfigurationExpression());
        services.AddSingleton<IMapTuple, MapFromAndMapToProfile>();
        return services;
    }

    /// <summary>
    /// 应用模块服务
    /// </summary>
    /// <param name="provider">服务提供者</param>
    public override Task UseModule(IServiceProvider provider)
    {
        var logger = provider.GetLogger<AutoMapperModule>();
        var cfg = provider.GetRequiredService<MapperConfigurationExpression>();

        //获取已注册到IoC的所有Profile
        var tuples = provider.GetServices<IMapTuple>().OrderBy(m => m.Order).ToArray();
        foreach (var mapTuple in tuples)
        {
            mapTuple.CreateMap();
            cfg.AddProfile(mapTuple as Profile);
            logger.LogInformation(ResAutoMapper.Format_Init_Mapping_Pair, mapTuple.GetType());
        }

        var configuration = new MapperConfiguration(cfg);
        configuration.CompileMappings();
        var mapper = new AutoMapperMapper(configuration);
        MapperExtensions.SetMapper(mapper);
        logger.LogInformation(ResAutoMapper.Format_Init_Mapping_MapperExtensions, mapper.GetType());

        return base.UseModule(provider);
    }
}
